From d2d93a955580cf295604ce2533f529d97828c009 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Thu, 8 Sep 2005 17:02:14 +0000 Subject: [PATCH] made simple fishes work in the core --- ChangeLog | 23 ++++++ babl/babl-classes.h | 59 ++++++--------- babl/babl-component.c | 4 - babl/babl-conversion.c | 168 ++++++++++++++++++++--------------------- babl/babl-core.c | 2 +- babl/babl-fish.c | 80 +++++++++++++++++--- babl/babl-format.c | 16 ++-- babl/babl-internal.c | 50 ++++++++++-- babl/babl-internal.h | 3 + babl/babl-introspect.c | 12 +-- babl/babl-model.c | 8 +- 11 files changed, 260 insertions(+), 165 deletions(-) diff --git a/ChangeLog b/ChangeLog index ea044c2..0b9ed28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2005-09-08 Øyvind Kolås + + Made simple fishes work in the core. + + * babl/babl-classes.h: reduced number of conversion classes. + removed unused from and to members in struct. + * babl/babl-conversion.c: (conversion_new), (babl_conversion_new), + (babl_conversion_linear_process), (babl_conversion_plane_process), + (babl_conversion_planar_process), (babl_conversion_process): + * babl/babl-component.c: (each_babl_component_destroy), + (component_new): removed unused from and to members. + * babl/babl-fish.c: (babl_conversion_find2), + (babl_conversion_find), (babl_fish_reference), (babl_fish_simple), + (babl_fish), (convert_to_double), (convert_from_double), + (babl_fish_reference_process): use fast path if found directly in a + simple fishes. + * babl/babl-format.c: (babl_format_new): + * babl/babl-internal.c: (babl_process): + * babl/babl-internal.h: + * babl/babl-introspect.c: (each_introspect): + * babl/babl-model.c: (babl_model_new): + * babl/babl-core.c: (babl_core_init): s/linear/plane/ + 2005-09-08 Øyvind Kolås * AUTHORS: Added Micahel Schumacher, and email addresses. diff --git a/babl/babl-classes.h b/babl/babl-classes.h index 8285a86..a4e2989 100644 --- a/babl/babl-classes.h +++ b/babl/babl-classes.h @@ -22,12 +22,19 @@ /* Type and Format */ typedef long (*BablFuncLinear) (void *src, + void *dst, + long n); + +/* Signature of functions registered for reference type + * conversions, + */ +typedef long (*BablFuncPlane) (void *src, void *dst, int src_pitch, int dst_pitch, long n); -/* TypePlanar, ModelPlanar and FormatPlanar */ +/* TypePlanar,ModelPlanar and FormatPlanar */ typedef long (*BablFuncPlanar) (int src_bands, void *src[], int src_pitch[], @@ -36,6 +43,7 @@ typedef long (*BablFuncPlanar) (int src_bands, int dst_pitch[], long n); +#if 0 typedef long (*BablFuncPlanarBit) (int src_bands, void *src[], int src_bit[], @@ -47,6 +55,7 @@ typedef long (*BablFuncPlanarBit) (int src_bands, int dst_pitch[], int dst_bit_pitch[], long n); +#endif /* magic number used at the start of all babl objects, used to do * differentiation in polymorphic functions. (as well as manual @@ -65,14 +74,13 @@ typedef enum { BABL_FORMAT, BABL_CONVERSION, - BABL_CONVERSION_TYPE, - BABL_CONVERSION_TYPE_PLANAR, - BABL_CONVERSION_MODEL_PLANAR, - BABL_CONVERSION_FORMAT, - BABL_CONVERSION_FORMAT_PLANAR, + BABL_CONVERSION_LINEAR, + BABL_CONVERSION_PLANE, + BABL_CONVERSION_PLANAR, BABL_FISH, BABL_FISH_REFERENCE, + BABL_FISH_SIMPLE, BABL_IMAGE, BABL_EXTENSION, @@ -103,38 +111,13 @@ BablConversion { union { BablFuncLinear linear; + BablFuncPlane plane; BablFuncPlanar planar; - BablFuncPlanarBit planar_bit; } function; int processings; long pixels; } BablConversion; -typedef struct { - BablConversion conversion; - BablConversion *from_double; - BablConversion *to_double; -} BablConversionType; - -typedef struct -{ - BablConversion conversion; -} BablConversionTypePlanar; - -typedef struct -{ - BablConversion conversion; -} BablConversionModelPlanar; - -typedef struct -{ - BablConversion conversion; -} BablConversionFormat; - -typedef struct -{ - BablConversion conversion; -} BablConversionFormatPlanar; typedef struct { @@ -177,8 +160,6 @@ typedef struct typedef struct { BablInstance instance; - BablConversion **from; /*< NULL terminated list of conversions from class */ - BablConversion **to; /*< NULL terminated list of conversions to class */ int luma; int chroma; int alpha; @@ -249,6 +230,15 @@ typedef struct BablFish fish; } BablFishReference; +/* BablFishSimple is the simplest type of fish, wrapping a single + * conversion function + */ +typedef struct +{ + BablFish fish; + BablConversion *conversion; +} BablFishSimple; + typedef struct { BablInstance instance; /* path to .so / .dll is stored in instance name */ @@ -269,6 +259,7 @@ typedef union BablImage image; BablFish fish; BablFishReference reference_fish; + BablFishSimple fish_simple; BablExtension extension; } Babl; diff --git a/babl/babl-component.c b/babl/babl-component.c index 1d5b0d8..37ebb7b 100644 --- a/babl/babl-component.c +++ b/babl/babl-component.c @@ -28,8 +28,6 @@ static int each_babl_component_destroy (Babl *babl, void *data) { - babl_free (babl->component.from); - babl_free (babl->component.to); babl_free (babl); return 0; /* continue iterating */ } @@ -52,8 +50,6 @@ component_new (const char *name, babl->component.luma = luma; babl->component.chroma = chroma; babl->component.alpha = alpha; - babl->component.from = NULL; - babl->component.to = NULL; return babl; } diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c index 4e85b9d..9a52b1b 100644 --- a/babl/babl-conversion.c +++ b/babl/babl-conversion.c @@ -39,75 +39,54 @@ conversion_new (const char *name, int time_cost, int loss, BablFuncLinear linear, - BablFuncPlanar planar, - BablFuncPlanarBit planar_bit) + BablFuncPlane plane, + BablFuncPlanar planar) { Babl *babl = NULL; - /* destination is of same type as source */ + babl_assert (source->class_type == + destination->class_type); + + if (linear) + { + babl = babl_malloc (sizeof (BablConversion)); + babl->class_type = BABL_CONVERSION_LINEAR; + babl->conversion.function.linear = linear; + } + else if (plane) + { + babl = babl_malloc (sizeof (BablConversion)); + babl->class_type = BABL_CONVERSION_PLANE; + babl->conversion.function.plane = plane; + } + else if (planar) + { + babl = babl_malloc (sizeof (BablConversion)); + babl->class_type = BABL_CONVERSION_PLANAR; + babl->conversion.function.planar = planar; + } switch (source->class_type) { case BABL_TYPE: - if (linear) - { - babl = babl_malloc (sizeof (BablConversionType)); - babl->class_type = BABL_CONVERSION_TYPE; - babl->conversion.function.linear = linear; - } - else if (planar) - { - babl = babl_malloc (sizeof (BablConversionTypePlanar)); - babl->class_type = BABL_CONVERSION_TYPE_PLANAR; - babl->conversion.function.planar = planar; - } - else if (planar_bit) - { - babl_log ("planar_bit support not implemented yet"); - } break; case BABL_MODEL: if (linear) { - babl_log ("linear support for model conversion not supported"); - } - else if (planar) - { - babl = babl_malloc (sizeof (BablConversionModelPlanar)); - babl->class_type = BABL_CONVERSION_MODEL_PLANAR; - babl->conversion.function.planar = planar; + babl_fatal ("linear support for %s not supported", + babl_class_name (source->class_type)); } - else if (planar_bit) + else if (plane) { - babl_log ("planar_bit support for model conversion not supported"); + babl_fatal ("plane support for %s not supported", + babl_class_name (source->class_type)); } break; case BABL_FORMAT: - if (linear) - { - babl = babl_malloc (sizeof (BablConversionFormat)); - babl->class_type = BABL_CONVERSION_FORMAT; - babl->conversion.function.linear = linear; - } - else if (planar) - { - babl = babl_malloc (sizeof (BablConversionFormatPlanar)); - babl->class_type = BABL_CONVERSION_FORMAT_PLANAR; - babl->conversion.function.planar = planar; - } - else if (planar_bit) - { - babl_log ("planar_bit support for pixelformat conversion not supported"); - } break; default: - babl_log ("%s unexpected", babl_class_name (babl->class_type)); + babl_fatal ("%s unexpected", babl_class_name (babl->class_type)); break; } - if (!babl) - { - babl_log ("args=(name='%s', ...): creation failed", name); - return NULL; - } babl->instance.id = id; babl->instance.name = babl_strdup (name); @@ -154,8 +133,8 @@ babl_conversion_new (void *first_arg, int time_cost = 0; int loss = 0; BablFuncLinear linear = NULL; + BablFuncPlane plane = NULL; BablFuncPlanar planar = NULL; - BablFuncPlanarBit planar_bit = NULL; int got_func = 0; const char *arg = first_arg; @@ -183,27 +162,27 @@ babl_conversion_new (void *first_arg, { if (got_func++) { - babl_log ("already got a conversion func, registration of multiple might be possible later\n"); + babl_fatal ("already got a conversion func\n"); } linear = va_arg (varg, BablFuncLinear); } - else if (!strcmp (arg, "planar")) + else if (!strcmp (arg, "plane")) { if (got_func++) { - babl_log ("already got a conversion func, registration of multiple might be possible later\n"); + babl_fatal ("already got a conversion func\n"); } - planar = va_arg (varg, BablFuncPlanar); + plane = va_arg (varg, BablFuncPlane); } - else if (!strcmp (arg, "planar-bit")) + else if (!strcmp (arg, "planar")) { if (got_func++) { - babl_log ("already got a conversion func, registration of multiple might be possible later\n"); + babl_fatal ("already got a conversion func\n"); } - planar_bit = va_arg (varg, BablFuncPlanarBit); + planar = va_arg (varg, BablFuncPlanar); } else if (!strcmp (arg, "time-cost")) @@ -227,8 +206,8 @@ babl_conversion_new (void *first_arg, assert (source); assert (destination); - babl = conversion_new (create_name (source, destination), id, source, destination, time_cost, loss, linear, - planar, planar_bit); + babl = conversion_new (create_name (source, destination), + id, source, destination, time_cost, loss, linear, plane, planar); { Babl *ret = babl_db_insert (db, babl); @@ -242,12 +221,22 @@ static long babl_conversion_linear_process (BablConversion *conversion, void *source, void *destination, - int src_pitch, - int dst_pitch, long n) { - conversion->function.linear (source, destination, src_pitch, dst_pitch, n); - return n; + return conversion->function.linear (source, destination, n); +} + +static long +babl_conversion_plane_process (BablConversion *conversion, + void *source, + void *destination, + int src_pitch, + int dst_pitch, + long n) +{ + return conversion->function.plane (source, destination, + src_pitch, dst_pitch, + n); } static long @@ -267,14 +256,13 @@ babl_conversion_planar_process (BablConversion *conversion, memcpy (src_data, source->data, sizeof (void*) * source->components); memcpy (dst_data, destination->data, sizeof (void*) * destination->components); - conversion->function.planar (source->components, - src_data, - source->pitch, - destination->components, - dst_data, - destination->pitch, - n); - return n; + return conversion->function.planar (source->components, + src_data, + source->pitch, + destination->components, + dst_data, + destination->pitch, + n); } long @@ -287,7 +275,7 @@ babl_conversion_process (BablConversion *conversion, switch (BABL(conversion)->class_type) { - case BABL_CONVERSION_TYPE: + case BABL_CONVERSION_PLANE: { void *src_data = NULL; void *dst_data = NULL; @@ -302,32 +290,30 @@ babl_conversion_process (BablConversion *conversion, src_data = img->data[0]; src_pitch = img->pitch[0]; } - if (!src_data) - src_data=source; - if (!src_pitch) - src_pitch=BABL(conversion->source)->type.bits/8; - - if (BABL_IS_BABL(destination)) { - BablImage *img; + BablImage *img = (BablImage*)destination; - img = (BablImage*)destination; dst_data = img->data[0]; dst_pitch = img->pitch[0]; } + + if (!src_data) + src_data=source; + if (!src_pitch) + src_pitch=BABL(conversion->source)->type.bits/8; if (!dst_data) dst_data=destination; if (!dst_pitch) dst_pitch=BABL(conversion->destination)->type.bits/8; - babl_conversion_linear_process (conversion, - src_data, dst_data, - src_pitch, dst_pitch, - n); + babl_conversion_plane_process (conversion, + src_data, dst_data, + src_pitch, dst_pitch, + n); } break; - case BABL_CONVERSION_MODEL_PLANAR: + case BABL_CONVERSION_PLANAR: babl_assert (BABL_IS_BABL (source)); babl_assert (BABL_IS_BABL (destination)); @@ -336,6 +322,16 @@ babl_conversion_process (BablConversion *conversion, (BablImage*) destination, n); break; + case BABL_CONVERSION_LINEAR: + babl_assert (!BABL_IS_BABL (source)); + babl_assert (!BABL_IS_BABL (destination)); + + babl_conversion_linear_process (conversion, + source, + destination, + n); + break; + default: babl_log ("args=(%s, %p, %p, %li) unhandled conversion type: %s", conversion->instance.name, source, destination, n, diff --git a/babl/babl-core.c b/babl/babl-core.c index c1b0684..bcc54f9 100644 --- a/babl/babl-core.c +++ b/babl/babl-core.c @@ -85,7 +85,7 @@ babl_core_init (void) babl_conversion_new ( babl_type_id (BABL_DOUBLE), babl_type_id (BABL_DOUBLE), - "linear", convert_double_double, + "plane", convert_double_double, NULL ); diff --git a/babl/babl-fish.c b/babl/babl-fish.c index 2ba562b..2dd6a73 100644 --- a/babl/babl-fish.c +++ b/babl/babl-fish.c @@ -57,14 +57,14 @@ typedef struct SearchData BablConversion *result; } SearchData; -Babl *babl_conversion_find (void *source, +Babl *babl_conversion_find2 (void *source, void *destination) { int i=0; Babl **conversion; conversion = (void*)BABL(source)->type.from; - while (conversion[i]) + while (conversion && conversion[i]) { if (conversion[i]->conversion.destination == destination) return (Babl*)conversion[i]; @@ -75,9 +75,27 @@ Babl *babl_conversion_find (void *source, } +Babl *babl_conversion_find (void *source, + void *destination) +{ + int i=0; + Babl **conversion; + + conversion = (void*)BABL(source)->type.from; + while (conversion && conversion[i]) + { + if (conversion[i]->conversion.destination == destination) + return (Babl*)conversion[i]; + i++; + } + return NULL; +} + + + Babl * -babl_fish_reference_new (Babl *source, - Babl *destination) +babl_fish_reference (Babl *source, + Babl *destination) { Babl *babl = NULL; char *name = create_name (source, destination, 1); @@ -108,6 +126,39 @@ babl_fish_reference_new (Babl *source, } } +Babl * +babl_fish_simple (BablConversion *conversion) +{ + Babl *babl = NULL; + char *name; + + babl_assert (BABL_IS_BABL (conversion)); + + name = create_name (BABL(conversion->source), + BABL(conversion->destination), + 0); + + babl = babl_malloc (sizeof (BablFishSimple) + + strlen (name) + 1); + babl->class_type = BABL_FISH_SIMPLE; + babl->instance.id = 0; + babl->instance.name = ((void *)babl) + sizeof(BablFishSimple); + strcpy (babl->instance.name, name); + babl->fish.source = (union Babl*)conversion->source; + babl->fish.destination = (union Babl*)conversion->destination; + + babl->fish.processings = 0; + babl->fish.pixels = 0; + babl->fish_simple.conversion = conversion; + + { + Babl *ret = babl_db_insert (db, babl); + if (ret!=babl) + babl_free (babl); + return ret; + } +} + Babl * babl_fish (void *source, void *destination) @@ -149,8 +200,17 @@ babl_fish (void *source, babl_log ("args=(%p, %p) destination format invalid", source, destination); return NULL; } - - return babl_fish_reference_new (source_format, destination_format); + + + { + Babl *shortcut_conversion = babl_conversion_find (source_format, destination_format); + + if (shortcut_conversion) + { + return babl_fish_simple (&(shortcut_conversion->conversion)); + } + } + return babl_fish_reference (source_format, destination_format); } @@ -201,7 +261,7 @@ convert_to_double (BablFormat *source_fmt, } babl_process ( - babl_conversion_find (src_img->type[0], dst_img->type[0]), + babl_conversion_find2 (src_img->type[0], dst_img->type[0]), src_img, dst_img, n); src_img->data[0] += src_img->type[0]->bits/8; @@ -256,7 +316,7 @@ convert_from_double (BablFormat *destination_fmt, } babl_process ( - babl_conversion_find (src_img->type[0], dst_img->type[0]), + babl_conversion_find2 (src_img->type[0], dst_img->type[0]), src_img, dst_img, n); dst_img->data[0] += dst_img->type[0]->bits/8; @@ -350,7 +410,7 @@ babl_fish_reference_process (Babl *babl, ); babl_process ( - babl_conversion_find ( + babl_conversion_find2 ( BABL(babl->fish.source)->format.model, babl_model_id (BABL_RGBA) ), @@ -358,7 +418,7 @@ babl_fish_reference_process (Babl *babl, n); babl_process ( - babl_conversion_find ( + babl_conversion_find2 ( babl_model_id (BABL_RGBA), BABL(babl->fish.destination)->format.model ), diff --git a/babl/babl-format.c b/babl/babl-format.c index cfd0056..606105f 100644 --- a/babl/babl-format.c +++ b/babl/babl-format.c @@ -167,8 +167,8 @@ babl_format_new (void *first_arg, case BABL_COMPONENT: if (!model) { - babl_log ("no model specified before component %s", - babl->instance.name); + babl_fatal ("no model specified before component %s", + babl->instance.name); } component [components] = (BablComponent*) babl; type [components] = current_type; @@ -177,8 +177,8 @@ babl_format_new (void *first_arg, if (components>=BABL_MAX_COMPONENTS) { - babl_log ("maximum number of components (%i) exceeded for %s", - BABL_MAX_COMPONENTS, name); + babl_fatal ("maximum number of components (%i) exceeded for %s", + BABL_MAX_COMPONENTS, name); } break; case BABL_SAMPLING: @@ -195,11 +195,9 @@ babl_format_new (void *first_arg, case BABL_INSTANCE: case BABL_FORMAT: case BABL_CONVERSION: - case BABL_CONVERSION_TYPE: - case BABL_CONVERSION_TYPE_PLANAR: - case BABL_CONVERSION_MODEL_PLANAR: - case BABL_CONVERSION_FORMAT: - case BABL_CONVERSION_FORMAT_PLANAR: + case BABL_CONVERSION_LINEAR: + case BABL_CONVERSION_PLANE: + case BABL_CONVERSION_PLANAR: case BABL_FISH: case BABL_FISH_REFERENCE: case BABL_IMAGE: diff --git a/babl/babl-internal.c b/babl/babl-internal.c index 274d87b..0cde94e 100644 --- a/babl/babl-internal.c +++ b/babl/babl-internal.c @@ -30,13 +30,12 @@ static const char *class_names[] = "BablModel", "BablFormat", "BablConversion", - "BablConversionType", - "BablConversionTypePlanar", - "BablConversionModelPlanar", - "BablConversionFormat", - "BablConversionFormatPlanar", + "BablConversionLinear", + "BablConversionPlane", + "BablConversionPlanar", "BablFish", "BablFishReference", + "BablFishSimple", "BablImage", "BablExtenstion", "BablSky" @@ -96,7 +95,7 @@ babl_process (Babl *babl, /* matches all conversion classes */ if (babl->class_type >= BABL_CONVERSION && - babl->class_type <= BABL_CONVERSION_FORMAT_PLANAR) + babl->class_type <= BABL_CONVERSION_PLANAR) return babl_conversion_process (babl, source, destination, n); if (babl->class_type == BABL_FISH) @@ -106,6 +105,7 @@ babl_process (Babl *babl, { BablImage *source_image = NULL; BablImage *destination_image = NULL; + long ret=0; if (BABL_IS_BABL (source)) source_image = source; @@ -118,12 +118,46 @@ babl_process (Babl *babl, destination_image = (BablImage*) babl_image_from_linear ( destination, (Babl*)babl->fish.destination); - babl_fish_reference_process (babl, source, destination, n); + ret = babl_fish_reference_process (babl, source, destination, n); babl_free (source_image); babl_free (destination_image); - return 0; + return ret; + } + + if (babl->class_type == BABL_FISH_SIMPLE) + { + long ret=0; + BablImage *source_image = NULL; + BablImage *destination_image = NULL; + + if (BABL_IS_BABL (source)) + source_image = source; + if (!source_image) + source_image = (BablImage*) babl_image_from_linear ( + source, (Babl*)babl->fish.source); + if (BABL_IS_BABL (destination)) + destination_image = destination; + if (!destination_image) + destination_image = (BablImage*) babl_image_from_linear ( + destination, (Babl*)babl->fish.destination); + + if (BABL(babl->fish_simple.conversion)->class_type==BABL_CONVERSION_LINEAR) + { + ret = babl_conversion_process (BABL(babl->fish_simple.conversion), + source, destination, n); + } + else + { + ret = babl_conversion_process (BABL(babl->fish_simple.conversion), + source_image, destination_image, n); + } + + babl_free (source_image); + babl_free (destination_image); + + return ret; } babl_log ("eek"); diff --git a/babl/babl-internal.h b/babl/babl-internal.h index cacff5e..c516f62 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -51,6 +51,9 @@ int babl_fish_reference_process (Babl *babl, BablImage *source, BablImage *destination, long n); +Babl * babl_fish_reference (Babl *source, + Babl *destination); +Babl * babl_fish_simple (BablConversion *conversion); Babl * babl_image_from_linear (void *buffer, Babl *format); Babl * babl_image_double_from_image (Babl *source); diff --git a/babl/babl-introspect.c b/babl/babl-introspect.c index 12b4ffd..d440bc4 100644 --- a/babl/babl-introspect.c +++ b/babl/babl-introspect.c @@ -201,7 +201,6 @@ each_introspect (Babl *babl, item_conversions_introspect (babl); break; case BABL_COMPONENT: - item_conversions_introspect (babl); break; case BABL_MODEL: model_introspect (babl); @@ -216,17 +215,14 @@ each_introspect (Babl *babl, item_conversions_introspect (babl); break; case BABL_CONVERSION: - case BABL_CONVERSION_TYPE: - case BABL_CONVERSION_TYPE_PLANAR: - case BABL_CONVERSION_MODEL_PLANAR: - case BABL_CONVERSION_FORMAT: - case BABL_CONVERSION_FORMAT_PLANAR: + case BABL_CONVERSION_PLANE: + case BABL_CONVERSION_PLANAR: + case BABL_CONVERSION_LINEAR: conversion_introspect (babl); break; case BABL_FISH: - fish_introspect (babl); - break; case BABL_FISH_REFERENCE: + case BABL_FISH_SIMPLE: fish_introspect (babl); break; default: diff --git a/babl/babl-model.c b/babl/babl-model.c index e43d23e..0b5faaa 100644 --- a/babl/babl-model.c +++ b/babl/babl-model.c @@ -121,11 +121,9 @@ babl_model_new (void *first_argument, case BABL_CONVERSION: - case BABL_CONVERSION_TYPE: - case BABL_CONVERSION_TYPE_PLANAR: - case BABL_CONVERSION_MODEL_PLANAR: - case BABL_CONVERSION_FORMAT: - case BABL_CONVERSION_FORMAT_PLANAR: + case BABL_CONVERSION_LINEAR: + case BABL_CONVERSION_PLANE: + case BABL_CONVERSION_PLANAR: case BABL_FISH: case BABL_FISH_REFERENCE: case BABL_IMAGE: -- 2.30.2